// =============================================================================
//                         FILE DETAILS
// Project          : IM2
// Author           : Andy Chen
// File             : ram.sv
// Title            : Single port sram wrapper
// Version          : 0.1
// Last modified	  : Jun 16 2008
// =============================================================================
//Log:
//Created by Andy Chen on Jun 16 2008

//synopsys translate_off
/////////////////////////////////////////////////////
// Module interface
/////////////////////////////////////////////////////

module xpip_ram(clk, radr, wadr, wr, be, datai,
               datao, datao_d);
                 
/////////////////////////////////////////////////////
// Parameters
/////////////////////////////////////////////////////
  parameter addr_width = 10,
            num_words  = 'b01 << addr_width,
            word_width = 32,
            bc_width   = 8,
            be_width   = (word_width - 1) / bc_width + 1,
            two_port   = 0,
            bp         = 0;
  
/////////////////////////////////////////////////////
// Internal nets and registers 
/////////////////////////////////////////////////////
  input logic clk;
  input logic [addr_width-1:0] radr, wadr;
  input logic wr;
  input logic [be_width-1:0] be;
  input logic [word_width-1:0] datai;
  output logic [word_width-1:0] datao, datao_d;  
  
  logic [word_width-1:0] ram[num_words-1:0];
  logic wr_d, bpv;
  logic [word_width-1:0] datai_d;
  logic [word_width-1:0] datao_p;
  
  genvar i;
  
  assign datao = (wr_d && !two_port) ? 'x : (bpv ? datai_d : datao_p);
  
/////////////////////////////////////////////////////
// Functions and tasks
/////////////////////////////////////////////////////
//optional
  
/////////////////////////////////////////////////////
// Instances
/////////////////////////////////////////////////////
//optional

/////////////////////////////////////////////////////
// Sequential logic
/////////////////////////////////////////////////////
  always_ff@(posedge clk)
  begin
  	wr_d <= wr;
  	datao_d <= datao;
  	bpv <= bp && wr && wadr == radr;
  	datai_d <= datai;
  	datao_p <= ram[radr];
  end

  for(i = 0; i < be_width; i++)
  begin
   	always_ff@(posedge clk)
       if(be[i] && wr) begin
         if(i == (be_width-1))
           ram[wadr][word_width-1:i*bc_width] <= datai[word_width-1:i*bc_width];
         else
           ram[wadr][i*bc_width+bc_width-1:i*bc_width] <= datai[i*bc_width+bc_width-1:i*bc_width];
       end
  end

/////////////////////////////////////////////////////
// Combinational logic
/////////////////////////////////////////////////////
//required

/////////////////////////////////////////////////////
// Initials
/////////////////////////////////////////////////////

endmodule
//synopsys translate_on